﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Collections.ObjectModel;
using System.IO;

namespace Chaos.stream
{
    public class ostream_xml : stream
    {
        XmlWriter writer;

        public ostream_xml()
        {

        }

        public void open(String in_FilePath)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            writer = XmlTextWriter.Create(in_FilePath, settings);
        }

        public void open(Stream in_Stream)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            writer = XmlTextWriter.Create(in_Stream, settings);
        }
        
        public void close()
        {
            writer.WriteEndDocument();
            writer.Close();
        }
        
        public stream begin(String in_String)
        {
            writer.WriteStartElement(in_String);
            return this;
        }

        public stream end(String in_String)
        {
            writer.WriteEndElement();
            return this;
        }

        public stream serialize(String in_String, ref bool in_Value)
        {
            String s = in_Value.ToString();
            writer.WriteAttributeString(in_String, s);
            return this;
        }

        public stream serialize(String in_String, ref int in_Value)
        {            
            String s = in_Value.ToString();
            writer.WriteAttributeString(in_String, s);
            return this;
        }

        public stream serialize(String in_String, ref float in_Value)
        {
            writer.WriteAttributeString(in_String, in_Value.ToString());
            return this;
        }

        public stream serialize(String in_String, ref double in_Value)
        {
            writer.WriteAttributeString(in_String, in_Value.ToString());
            return this;
        }

        public stream serialize(String in_String, ref String in_Value)
        {
            writer.WriteAttributeString(in_String, in_Value.ToString());
            return this;
        }

        public stream serialize(String in_String, ref streamable in_Value)
        {
            try
            {
                writer.WriteStartElement(in_String);
                in_Value.serialize(this);
                writer.WriteEndElement();
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(in_String);
                System.Diagnostics.Debug.WriteLine(e.ToString());
            }
            return this;
        }

        public stream serialize(String in_String, ref Enum in_Value)
        {
            String s = in_Value.ToString();
            writer.WriteAttributeString(in_String, s);
            return this;
        }

        public stream serialize(String in_String, ref int[] in_Value)
        {
            writer.WriteStartElement(in_String);            
            foreach (int i in in_Value)
            {
                writer.WriteElementString("step", i.ToString());
            }          
            writer.WriteEndElement();
            return this;
        }

        public stream serialize(String in_String, ref float[] in_Value)
        {
            writer.WriteStartElement(in_String);
            foreach (float f in in_Value)
            {
                writer.WriteElementString("step", f.ToString());
            }
            writer.WriteEndElement();
            return this;
        }

        public stream serialize(String in_String, ref double[] in_Value)
        {
            writer.WriteStartElement(in_String);
            foreach (double f in in_Value)
            {
                writer.WriteElementString("step", f.ToString());
            }
            writer.WriteEndElement();
            return this;
        }

        public stream serialize(String in_String, ref String[] in_Value)
        {
            writer.WriteStartElement(in_String);
            foreach (String s in in_Value)
            {
                writer.WriteElementString("step", s);
            }
            writer.WriteEndElement();
            return this;
        }

        public stream serialize(String in_String, ref streamable[] in_Value)
        {
            try
            {
                writer.WriteStartElement(in_String);
                foreach (streamable s in in_Value)
                {
                    s.serialize(this);
                }
                writer.WriteEndElement();
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(in_String);
                System.Diagnostics.Debug.WriteLine(e.ToString());
            }
            return this;
        }

        public stream serialize<T>(String in_String, ref ObservableCollection<T> in_Value)
        {
            try
            {
                writer.WriteStartElement(in_String);
                foreach (T t in in_Value)
                {
                    streamable s = t as streamable;
                    s.serialize(this);
                }
                writer.WriteEndElement();
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(in_String);
                System.Diagnostics.Debug.WriteLine(e.ToString());
            }
            return this;
        }

        public bool isoutputstream()
        {
            return true;
        }

        public bool isinputstream()
        {
            return false;
        }

    }
}
